package com.zzj.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzj.base.Result;
import com.zzj.entity.Nurse;
import com.zzj.entity.NurseSchedule;
import com.zzj.feign.IInvitationApiFeign;
import com.zzj.model.dto.QueryListDTO;
import com.zzj.model.dto.schedule.nurse.FreeNurseDTO;
import com.zzj.model.dto.schedule.nurse.NurseApplyDTO;
import com.zzj.model.dto.schedule.nurse.NurseUpdateDTO;
import com.zzj.service.INurseScheduleService;
import com.zzj.service.INurseService;
import com.zzj.service.IUserService;
import com.zzj.service.RedisService;
import com.zzj.utils.JWTUtil;
import com.zzj.utils.QueryUtil;
import com.zzj.utils.Utils;
import jakarta.annotation.Resource;
import org.apache.http.HttpHeaders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zzj
 * @since 2023-02-16
 */
@RestController
@RequestMapping("/nurse")
public class NurseController {

    @Resource
    private INurseService nurseService;
    @Resource
    private IUserService userService;
    @Resource
    private INurseScheduleService nurseScheduleService;
    @Resource
    private RedisService redisService;
    @Resource
    private IInvitationApiFeign iInvitationApiFeign;

    /**
     * 申请
     *
     * @param in
     * @return
     */
    @Transactional
    @PostMapping("apply")
    public Result apply(@RequestBody @Validated NurseApplyDTO in) {
        Nurse nurse = JSONObject.parseObject(JSONObject.toJSONString(in), Nurse.class);
        String nurseJobNum = Utils.getNurseJobNum();
        nurse.setJobNum(nurseJobNum);

        if (in.getInvitationCode() != null && !Objects.equals(in.getInvitationCode(), "")) {
            String typeByInvitationCode = redisService.getTypeByInvitationCode(in.getInvitationCode());
            if (typeByInvitationCode == null) {
                return Result.error("邀请码不存在");
            }
            iInvitationApiFeign.use(in.getInvitationCode());
            nurse.setStatus(1);
            nurseService.save(nurse);
            userService.setUserStatus(in.getUsername(), 3);
            return Result.success("档案建立成功", nurse);
        } else {
            userService.setUserStatus(in.getUsername(), 33);
            nurseService.save(nurse);
            return Result.success("提交成功，等待审核");
        }
    }

    /**
     * 修改信息
     *
     * @param nurseUpdateDTO
     * @return
     */
    @Transactional
    @PostMapping("update")
    public Result update(@RequestBody @Validated NurseUpdateDTO nurseUpdateDTO) {
        UpdateWrapper<Nurse> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("username", nurseUpdateDTO.getUsername())
                .set("sex", nurseUpdateDTO.getSex())
                .set("department", nurseUpdateDTO.getDepartment())
                .set("phone", nurseUpdateDTO.getPhone());
        nurseService.update(updateWrapper);
        return Result.success("信息修改成功");
    }

    /**
     * 创建
     *
     * @param in
     * @return
     */
    @Transactional
    @PostMapping("create")
    public Result create(@RequestBody @Validated NurseApplyDTO in) {
        Nurse nurse = JSONObject.parseObject(JSONObject.toJSONString(in), Nurse.class);
        String nurseJobNum = Utils.getNurseJobNum();
        nurse.setJobNum(nurseJobNum);
        nurse.setStatus(1);
        nurseService.save(nurse);
        return Result.success("完善成功");
    }

    /**
     * token 获取 医护信息
     *
     * @param token
     * @return
     */
    @Transactional
    @PostMapping("info")
    public Result info(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token) {
        String username = JWTUtil.getUsername(token);
        Nurse one = nurseService.getNurseByUsername(username);
        return Result.success(one);
    }

    @Transactional
    @PostMapping("infoById")
    public Result infoById(@RequestParam String id) {
        Nurse one = nurseService.getNurseById(Integer.parseInt(id));
        return Result.success(one);
    }

    @Transactional
    @PostMapping("infoByUsername")
    public Result infoByUsername(@RequestParam String username) {
        Nurse one = nurseService.getNurseByUsername(username);
        return Result.success(one);
    }

    @Transactional
    @PostMapping("formalList")
    public Result formalList(@RequestBody @Validated QueryListDTO in) {
        QueryWrapper<Nurse> queryWrapper = QueryUtil.paramsWrapper(in.getAndParams(), in.getOrParams(), in.getOrderParams());
        queryWrapper.eq("status", "1");
        Page<Nurse> nursePage = new Page<>(in.getPageNo(), in.getPageSize());
        IPage<Nurse> patientIPage = nurseService.getBaseMapper().selectPage(nursePage, queryWrapper);
        return Result.success(patientIPage);
    }

    /**
     * 管理员权限
     *
     * @param token
     * @return
     */
    @Transactional
    @PostMapping("agreeByUsername")
    public Result agreeByUsername(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                                  @RequestParam(value = "targetUsername") String targetUsername) {
        if (!userService.isAdmin(token)) {
            return Result.error("无权操作");
        }
        userService.setUserStatus(targetUsername, 3);
        nurseService.setNurseStatus(targetUsername, 1);
        return Result.success("已同意");
    }

    /**
     * 管理员权限
     *
     * @param token
     * @return
     */
    @Transactional
    @PostMapping("disAgreeByUsername")
    public Result disAgreeByUsername(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String token,
                                     @RequestParam(value = "targetUsername") String targetUsername) {
        if (!userService.isAdmin(token)) {
            return Result.error("无权操作");
        }
        userService.setUserStatus(targetUsername, 333);
        nurseService.setNurseStatus(targetUsername, 2);
        return Result.success("已拒绝");
    }

    /**
     * 时间段空闲医护
     *
     * @param in
     * @return
     */
    @PostMapping("freeList")
    public Result freeList(@RequestBody @Validated FreeNurseDTO in) {


        //查询这个时间段有工作的护士
        List<NurseSchedule> list = nurseScheduleService.lambdaQuery()
                .between(NurseSchedule::getStart, in.getStart(), in.getEnd())
                .or().between(NurseSchedule::getEnd, in.getStart(), in.getEnd())
                .or(i -> i.ge(NurseSchedule::getEnd, in.getEnd()).le(NurseSchedule::getStart, in.getStart()))
                .list();

        //将这群护士排除

        QueryWrapper<Nurse> queryWrapper = QueryUtil.paramsWrapper(in.getAndParams(), in.getOrParams(), in.getOrderParams());
        for (NurseSchedule nurseSchedule : list) {
            queryWrapper.ne("username", nurseSchedule.getUsername());
        }
        queryWrapper.eq("status", 1);
        Page<Nurse> nursePage = new Page<>(in.getPageNo(), in.getPageSize());
        IPage<Nurse> patientIPage = nurseService.getBaseMapper().selectPage(nursePage, queryWrapper);
        return Result.success(patientIPage);
    }

}
